#include "protocol_list.h"
#include "protocol_board.h"

MessageListNode_t MessageCreateTableList(void)
{
  MessageListNode_t MessageListNode = (MessageListNode_t)ProtocolMessageMalloc(sizeof(MessageTable_t));
  if (MessageListNode != NULL)
  {
    memset(MessageListNode, 0, sizeof(MessageTable_t));

    MessageListNode->NextItem = MessageListNode;
    MessageListNode->PreviousItem = MessageListNode;
  }

  return MessageListNode;
}

void MessageListDestory(MessageListNode_t HeadNode)
{
  if (HeadNode != NULL)
  {
    MessageListNode_t CurrectNode = HeadNode->NextItem;
    while (CurrectNode != HeadNode)
    {
      MessageListNode_t TmpNoded = CurrectNode->NextItem;
      ProtocolMessageFree(CurrectNode);

      CurrectNode = TmpNoded;
    }

    ProtocolMessageFree(HeadNode);
  }
}

MessageListNode_t MessageListFind(MessageListNode_t HeadNode, uint32_t TriggerTime)
{
  if (HeadNode != NULL)
  {
    MessageListNode_t CurrectNode = HeadNode->NextItem;
    while (CurrectNode != HeadNode)
    {
      if (CurrectNode->Message.TriggerTime == TriggerTime)
        return CurrectNode;

      CurrectNode = CurrectNode->NextItem;
    }
  }

  return NULL;
}

MessageListNode_t MessageBuyNode(MessageDataPacket_t *pFileTable)
{
  MessageListNode_t Node = NULL;

  if (pFileTable != NULL)
  {
    Node = (MessageListNode_t)ProtocolMessageMalloc(sizeof(MessageTable_t));
    if (Node != NULL)
    {
      memset(Node, 0, sizeof(MessageTable_t));

      memcpy(&Node->Message, pFileTable, sizeof(MessageDataPacket_t));
      Node->NextItem = NULL;
      Node->PreviousItem = NULL;
    }
  }

  return Node;
}

void MessageInsertionNode(MessageListNode_t Pos, MessageDataPacket_t *pFileTable)
{
  if ((Pos != NULL) && (pFileTable != NULL))
  {
    MessageListNode_t NewNode = MessageBuyNode(pFileTable);

    if (NewNode != NULL)
    {
      MessageListNode_t Parent = Pos->PreviousItem;

      Parent->NextItem = NewNode;
      NewNode->PreviousItem = Parent;
      NewNode->NextItem = Pos;
      Pos->PreviousItem = NewNode;
    }
  }
}

void MessageListErase(MessageListNode_t Pos)
{
  if (Pos != NULL)
  {
    MessageListNode_t PosNext = Pos->NextItem;
    MessageListNode_t PosPrev = Pos->PreviousItem;

    PosPrev->NextItem = PosNext;
    PosNext->PreviousItem = PosPrev;
    ProtocolMessageFree(Pos);
  }
}

bool MessageListPushBack(MessageListNode_t HeadNode, MessageDataPacket_t *pFileTable)
{
  if (HeadNode != NULL)
  {
    MessageListNode_t NewNode = MessageBuyNode(pFileTable);

    if (NewNode != NULL)
    {
      HeadNode->PreviousItem->NextItem = NewNode;
      NewNode->PreviousItem = HeadNode->PreviousItem;
      NewNode->NextItem = HeadNode;
      HeadNode->PreviousItem = NewNode;

      return true;
    }
  }

  return false;
}

void MessageListPopBack(MessageListNode_t HeadNode)
{
  if (HeadNode != NULL)
  {
    if (HeadNode->PreviousItem != HeadNode)
    {
      MessageListNode_t TmpNode = HeadNode->PreviousItem;

      HeadNode->PreviousItem = TmpNode->PreviousItem;
      TmpNode->PreviousItem->NextItem = HeadNode;
      ProtocolMessageFree(TmpNode);
      TmpNode = NULL;
    }
  }
}

void MessageListPushFront(MessageListNode_t HeadNode, MessageDataPacket_t *pFileTable)
{
  if ((HeadNode != NULL) && (pFileTable != NULL))
  {
    MessageListNode_t NewNode = MessageBuyNode(pFileTable);

    if (NewNode != NULL)
    {
      NewNode->NextItem = HeadNode->NextItem;
      NewNode->PreviousItem = HeadNode;
      HeadNode->NextItem->PreviousItem = NewNode;
      HeadNode->NextItem = NewNode;
    }
  }
}

void MessageListPopFront(MessageListNode_t HeadNode)
{
  if (HeadNode->NextItem != HeadNode)
  {
    MessageListNode_t Node = HeadNode->NextItem;

    Node->NextItem->PreviousItem = HeadNode;
    HeadNode->NextItem = Node->NextItem;
    ProtocolMessageFree(Node);
    Node = NULL;
  }
}

void MessagListPrintf(MessageListNode_t HeadNode)
{
  MessageListNode_t Currect = HeadNode->NextItem;

  while (Currect != HeadNode)
  {
    PRINT("size: %d,", Currect->Message.PacketSize);
    PRINT("id: %d,", Currect->Message.TriggerTime);
    PRINT("data: ");
    for (uint8_t i = 0; i < Currect->Message.PacketSize; i++)
      PRINT("%02X", Currect->Message.PacketData[i]);
    PRINT(".\r\n");

    Currect = Currect->NextItem;
  }
}
